package com.simen.downloader;

import android.content.Context;
import android.content.Intent;

import com.simen.downloader.exception.ToastException;
import com.simen.downloader.exception.UnInitError;
import com.simen.downloader.listener.DownloadListener;
import com.simen.downloader.listener.SimpleDownloadListener;
import com.simen.downloader.model.Filer;
import com.simen.downloader.model.LocalFile;
import com.simen.downloader.util.Constants;
import com.simen.downloader.util.AppLog;
import com.simen.downloader.util.FileStorageUtils;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * Created by zhangming on 16/4/11.
 */
public final class Downloader {
    private final Map<String, DownloadInfor> listeners = new WeakHashMap<>();
    private DownloadConfiguration configuration;
    private DownloadEngine engine;
    private DownloadListener baselistener;
    private volatile static Downloader instance;

    /**
     * Returns singleton class instance
     */
    public static Downloader getInstance() {
        if (instance == null) {
            synchronized (Downloader.class) {
                if (instance == null) {
                    instance = new Downloader();
                }
            }
        }
        return instance;
    }

    protected Downloader() {

    }

    public void init(DownloadConfiguration configuration) {
        this.configuration = configuration;
        this.engine = new DownloadEngine(configuration);
        if (configuration.openlist) {
            this.baselistener = new SimpleDownloadListener();
        }
    }

    DownloadConfiguration getConfiguration() {
        return configuration;
    }

    DownloadEngine getEngine() {
        return this.engine;
    }

    public boolean isInited() {
        return this.configuration != null;
    }

    public Filer getWork(String fileUrl) {
        ParcelFile storageFile = configuration.downloadCache.getWork(fileUrl);
        if (storageFile == null || storageFile.isCleared()) {
            return null;
        }
        return storageFile;
    }

    public void resumeAll(Context context, List<String> fileUrls, DownloadListener listener) {

    }

    public void resumeWork(Context context, String fileUrl, DownloadListener listener) {
        if (!isInited()) {
            throw new UnInitError("下载器没有初始化");
        }

        DownloadInfor downloadInfor = listeners.get(fileUrl);
        if (downloadInfor != null) {
            if ((!downloadInfor.isCollected()) && downloadInfor.loader.get() == listener) {
                //任务进行中
                ParcelFile storageFile = configuration.downloadCache.getWork(fileUrl);
                if (storageFile.isCompleted()) {
                    AppLog.e("文件早已下载完成" + storageFile.toString());
                    listener.onProgress(fileUrl, 100);
                    listener.onComplete(fileUrl, FileStorageUtils.getLocalFile(new File
                            (configuration.defaultOptions.fileDir), fileUrl));
                } else {
                    AppLog.e("文件下载中" + storageFile.toString());
                    Intent taskIntent = new Intent(context, DownloadService.class);
                    context.startService(taskIntent);
                }
                return;
            }
            downloadInfor.loader.reInit(listener);//新的listener
            return;
        } else {
            ParcelFile storageFile = configuration.downloadCache.getWork(fileUrl);//任务进行中
            if (storageFile != null && storageFile.isCompleted()) {
                AppLog.e("文件早已存在本地" + storageFile.toString());
                listener.onResume(fileUrl);
                listener.onProgress(fileUrl, 100);
                listener.onComplete(fileUrl, FileStorageUtils.getLocalFile(new File
                        (configuration.defaultOptions.fileDir), fileUrl));
                return;
            }
        }

        ParcelFile storageFile = new ParcelFile(fileUrl, Constants.WORKWAITING);
        configuration.downloadCache.setStatus(fileUrl, storageFile);

        downloadInfor = new DownloadInfor(fileUrl, configuration.defaultOptions, listener, baselistener);
        listeners.put(fileUrl, downloadInfor);

        Intent taskIntent = new Intent(context, DownloadService.class);
        taskIntent.putExtra("fileUrl", fileUrl);
        taskIntent.putExtra("baseUrl", fileUrl);
        taskIntent.putExtra("type", DownloadService.TYPE.resume);
        context.startService(taskIntent);
    }

    public void pauseWork(Context context, String fileUrl) {
        if (!isInited()) {
            throw new UnInitError("下载器没有初始化");
        }
        DownloadInfor downloadInfor = listeners.get(fileUrl);
        if (downloadInfor != null) {
            downloadInfor.run.set(false);
            listeners.put(fileUrl, null);
            listeners.remove(fileUrl);
            AppLog.d("回收任务 " + fileUrl + " " + false);
            return;
        }

        AppLog.d("任务不存在 " + fileUrl);
    }

    public void clearAllWork(Context context, boolean alsefile) {
        if (!isInited()) {
            throw new UnInitError("下载器没有初始化");
        }

        Iterator<String> iterator = listeners.keySet().iterator();
        while (iterator.hasNext()) {
            String fileUrl = iterator.next();
            DownloadInfor downloadInfor = listeners.get(fileUrl);

            if (alsefile) {
                configuration.downloadCache.setStatus(fileUrl, null);
            } else {
                ParcelFile file = configuration.downloadCache.getWork(fileUrl);
                if (file != null) {
                    file.setStatus(Constants.WORKCLEARED);
                }
            }
            if (downloadInfor != null) {
                if (!downloadInfor.isCollected()) {
                    downloadInfor.run.set(false);
                }
                listeners.get(fileUrl).run.set(false);
                listeners.put(fileUrl, null);
                iterator.remove();
                AppLog.d("清除任务 " + fileUrl);
            }

            if (alsefile) {
                if (FileStorageUtils.getDefaultLogFilePath(configuration.defaultOptions.fileDir,
                        fileUrl).exists() || FileStorageUtils.getDefaultFilePath(configuration
                        .defaultOptions.fileDir, fileUrl).exists()) {
                    engine.executeFileThread(new FileThread(engine, configuration.defaultOptions.fileDir,
                            fileUrl));
                } else {
                    AppLog.d("不存在该下载地址的记录文件 " + fileUrl);
                }
            }

        }
    }

    public void clearWork(Context context, String fileUrl, boolean alsefile) {
        if (!isInited()) {
            throw new UnInitError("下载器没有初始化");
        }

        if (alsefile) {
            configuration.downloadCache.setStatus(fileUrl, null);
        } else {
            ParcelFile file = configuration.downloadCache.getWork(fileUrl);
            if (file != null) {
                file.setStatus(Constants.WORKCLEARED);
            }
        }

        DownloadInfor downloadInfor = listeners.get(fileUrl);
        if (downloadInfor != null) {
            if (!downloadInfor.isCollected()) {
                downloadInfor.run.set(false);
            }
            listeners.put(fileUrl, null);
            listeners.remove(fileUrl);
            AppLog.d("清除任务 " + fileUrl);
        }
        if (alsefile) {
            if (FileStorageUtils.getDefaultLogFilePath(configuration.defaultOptions.fileDir,
                    fileUrl)
                    .exists() || FileStorageUtils.getDefaultFilePath(configuration
                    .defaultOptions.fileDir, fileUrl)
                    .exists()) {
                engine.executeFileThread(new FileThread(engine, configuration.defaultOptions.fileDir,
                        fileUrl));
            } else {
                AppLog.d("不存在该下载地址的记录文件 " + fileUrl);
            }
        }
    }

    DownloadInfor getDownloadInfor(String fileUrl) {
        return listeners.get(fileUrl);
    }

    //暂停全部任务
    public void pauseAll() {
        Iterator<String> iterator = listeners.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            listeners.get(key).run.set(false);
            listeners.put(key, null);
            iterator.remove();
        }
    }

    public void register(DownloadListener baselistener) {

    }
}
